package cn.ante.ymcc.service.impl;

import cn.ante.ymcc.domain.CourseType;
import cn.ante.ymcc.dto.CourseTypeCrumbDto;
import cn.ante.ymcc.dto.CourseTypeDto;
import cn.ante.ymcc.mapper.CourseTypeMapper;
import cn.ante.ymcc.service.ICourseTypeService;
import cn.ante.ymcc.util.AssertUtil;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 课程目录 服务实现类
 * </p>
 *
 * @author Nai
 * @since 2022-08-08
 */
@Service
@Slf4j
public class CourseTypeServiceImpl extends ServiceImpl<CourseTypeMapper, CourseType> implements ICourseTypeService {

    @Autowired
    private ICourseTypeService courseTypeService;

    @Autowired
    private RedisTemplate<Object,Object> redisTemplate;

    @Override
    @Cacheable(cacheNames = "order",key = "'Constance.RedisCourseTypeTree.REDIS_TREE_KEY'")
    public List<CourseType> treeData(){
        log.info("缓存中拿拿拿");
        return getTypeTree();
    }

    /**
    * @Description: 课程类型面包屑
    * @Author: Nai
    * @Version: 1.0
    * @Date:  2022/8/16 11:41
     * @return
    */
    @Override
    public List<CourseTypeCrumbDto> getCrumbs(Long courseTypeId) {
        // 判断非空
        AssertUtil.isNotNull(courseTypeId,"课程不能为空");

        // 查到所有的课程类型
        List<CourseType> courseTypes = courseTypeService.selectList(null);

       // 装进map里
        Map<Long, CourseType> collect = courseTypes.stream()
                .collect(Collectors.toMap(CourseType::getId, CourseType -> CourseType));

        // 根据课程id得到该课程类型
        CourseType courseType = collect.get(courseTypeId);

        // 创建一个放所有的集合
        List<CourseTypeCrumbDto> courseTypeCrumbDtos = new ArrayList<>();

        // 获取到课程类型的路径，得到每一个导航路径
        String path = courseType.getPath();
        List<Long> ids = Arrays.stream(path.split("\\.")).map(id -> Long.parseLong(id.trim())).collect(Collectors.toList());
        for (Long id: ids) {
            CourseTypeCrumbDto courseTypeCrumbDto = new CourseTypeCrumbDto();
            CourseType type = collect.get(id);
            courseTypeCrumbDto.setOwnerProductType(type);
            if (type.getPid() != null) {
                for (CourseType tmp : courseTypes) {
                    if (type.getPid().equals(tmp.getPid()) && !type.equals(tmp)) {
                        courseTypeCrumbDto.getOtherProductTypes().add(tmp);
                    }
                }
            }
            courseTypeCrumbDtos.add(courseTypeCrumbDto);
        }
        return courseTypeCrumbDtos;
    }

//    @Override
//    public List<CourseType> treeData(){
//        // 定义一个存入存入redis中树的key值进行标记
//        String key = RedisConstant.RedisCourseTypeTree.REDIS_TREE_KEY;
//        // 在redis中查找该key,看是否存在数据
//        List<CourseType> treeTmp = (List<CourseType>)redisTemplate.opsForValue().get(key);
//        log.info("这是redis中的数据");
//        if (treeTmp == null){
//            treeTmp = getTypeTree();
//            log.info("这是数据库");
//            redisTemplate.opsForValue().set(key,treeTmp);
//        }
//        return treeTmp;
//    }

    public List<CourseType> getTypeTree(){
        // 拿到所有的课程类型
        List<CourseType> courseTypes = courseTypeService.selectList(null);
//        HashMap<Long,CourseTypeDto> map = new HashMap<>();
        // 装CourseTypeDto的集合
        List<CourseTypeDto> courseTypeDtos = new ArrayList<>();
        // 装树形结构的最终集合
        List<CourseType> courseTypeTree = new ArrayList<>();
        // 遍历课程类型
//        for (CourseType courType:courseTypes) {
//            CourseTypeDto courseTypeDto = new CourseTypeDto();
//            BeanUtils.copyProperties(courType,courseTypeDto);
//            courseTypeDto.setLable(courType.getName());
//            courseTypeDto.setChildren(new ArrayList<>());
//            map.put(courseTypeDto.getId(),courseTypeDto);
//            courseTypeDtos.add(courseTypeDto);
//        }
        //根据id分组map<String，T>
//        Map<Long, CourseType> collect =
//                courseTypes.stream().collect(Collectors.toMap(CourseType::getId, CourseType -> CourseType));
//        String string1 = JSON.toJSONString(collect);
//        List dtoList = list.stream().map(e -> {
//                    UserDTO d = new UserDTO();
//                    BeanUtils.copyProperties(e, d);
//                    return d;
//                }).collect(Collectors.toList());
        courseTypeDtos = courseTypes.stream().map(courseType -> {
            CourseTypeDto courseTypeDto = new CourseTypeDto();
            BeanUtils.copyProperties(courseType,courseTypeDto);
            courseTypeDto.setLable(courseType.getName());
            courseTypeDto.setChildren(new ArrayList<>());
            return courseTypeDto;
        }).collect(Collectors.toList());
        Map<Long, CourseTypeDto> collect = courseTypeDtos.stream().collect(Collectors.toMap
                (CourseTypeDto::getId, CourseTypeDto -> CourseTypeDto));
        // 遍历CourseTypeDto的集合
        for (CourseTypeDto dto:courseTypeDtos) {
            // 拿到每个dto的pid
            CourseTypeDto courseTypeParent = collect.get(dto.getPid());
            // 根据对象的fuid拿到对象，当对象为kong的时候，表明这个对象时父对象
            if (courseTypeParent == null){
                courseTypeTree.add(dto);
                continue;
            }
            // 当不为空的时候，说明父对象存在，就将从父对象找到子类。将子类收入其中
            courseTypeParent.getChildren().add(dto);
        }
        return courseTypeTree;
    }

    @Override
    @CacheEvict(cacheNames = "order",key = "'Constance.RedisCourseTypeTree.REDIS_TREE_KEY'")
    public boolean updateById(CourseType entity) {
//        if (super.updateById(entity)) {
//            redisTemplate.delete(RedisConstant.RedisCourseTypeTree.REDIS_TREE_KEY);
//        }
        return super.updateById(entity);
    }

    @Override
    @CacheEvict(cacheNames = "order",key = "'Constance.RedisCourseTypeTree.REDIS_TREE_KEY'")
    public boolean insert(CourseType entity) {
//        if (super.insert(entity)) {
//            redisTemplate.delete(RedisConstant.RedisCourseTypeTree.REDIS_TREE_KEY);
//        }
        return super.insert(entity);
    }

    @Override
    @CacheEvict(cacheNames = "order",key = "'Constance.RedisCourseTypeTree.REDIS_TREE_KEY'")
    public boolean deleteById(Serializable id) {
//        if (super.deleteById(id)) {
//            redisTemplate.delete(RedisConstant.RedisCourseTypeTree.REDIS_TREE_KEY);
//        }
        return super.deleteById(id);
    }
}
